/*
 * File:   F16.h
 * Author: jcrada
 *
 * Created on 30 May 2011, 1:00 PM
 */

#ifndef ECB_CEC10_F16_H
#define	ECB_CEC10_F16_H

#include "ecb/benchmarks/cec10/CecProblem.h" 

#include "ecb/benchmarks/cec10/CecMath.h"
#include "ecb/operator/Permuted.h"
#include "ecb/operator/Grouped.h"
#include "ecb/operator/Shifted.h"
#include "ecb/benchmarks/cec10/CecRotated.h"
#include "ecb/function/Ackley.h"

namespace ecb{
    namespace cec10 {

        class F16 : public CecProblem {
        private:
            std::vector<Function*> sumAckley;
        public:

            F16(int dimensions, int mValue)
            : CecProblem("F16", "(D/m)-group Shifted and m-rotated Ackley's Function", dimensions,
            -32, 32, true, mValue, new CecRandom(16l)) {

                std::vector<scalar> shift = CecMath::ShiftVector(dimensions, _properties->getMinimum(), _properties->getMaximum(), randomizer());
                std::vector<int> permutation = CecMath::PermutationVector(dimensions, randomizer());
                std::vector<std::vector<scalar> > rotation = CecMath::RotationMatrix(mValue, randomizer());
                std::vector<scalar> permutedShift(dimensions, 0);
                for (int i = 0; i < dimensions; ++i) {
                    permutedShift[i] = shift[permutation[i]];
                }
                for (int k = 0; k < dimensions / mValue; ++k) {
                    sumAckley.push_back(
                            new Permuted(permutation, new Grouped(k * mValue, (k + 1) * mValue,
                            new Shifted(permutedShift, k * mValue, new CecRotated(rotation, new Ackley())))));
                }

            }

            ~F16() {
                for (size_t i = 0; i < sumAckley.size(); ++i) {
                    delete sumAckley[i];
                }
            }

            scalar f(const std::vector<scalar>& x) {
                scalar result = 0;
                for (size_t i = 0; i < sumAckley.size(); ++i) {
                    result += sumAckley[i]->f(x);
                }
                return result;
            }
        };
    }
}


#endif	/* ECB_CEC10_F16_H */

